#include "mainframe.h"
#include "pmclientdata.h"
#include "panellog.h"
#include "panelsumary.h"
#include "panelworkrequest.h"
#include "panelcost.h"
#include "paneltask.h"
#include "panelindicator.h"
#include "paneltag.h"
#include "dlgeditcost.h"
#include "wizardnewproject.h"
#include "pm/manager.h"
#include "pm/project.h"
#include "vm_version.h"
#include <wx/fileconf.h>
#include <boost/foreach.hpp>

/**
 * \class DlgAbout
 */
class DlgAbout : public DlgAboutGui
{
public:
	DlgAbout(wxWindow* parent)
	: DlgAboutGui(parent)
	{
		m_labelVersion->SetLabel(wxString::FromAscii(version::VERSION));
	}
};

static const wxString KEY_PERSPECTIVE = wxT("perspective");

MainFrame::MainFrame(wxWindow *parent) 
: MainFrameGui( parent )
{
    SetIcon(wxICON(A));
	
	// Add panes
	m_aui.SetManagedWindow(this);
	
	PanelLog* panelLog = new PanelLog(this);
	m_aui.AddPane(panelLog, wxAuiPaneInfo()
								.Name(wxT("log")).Caption(_("Log"))
								.Bottom()
								.MaximizeButton(true));
	
	m_panelSumary = new PanelSumary(this);
	m_aui.AddPane(m_panelSumary, wxAuiPaneInfo()
								.Name(wxT("summary")).Caption(_("Summary"))
								.Left());
								
	m_panelWorkRequest = new PanelWorkRequest(this);
	m_aui.AddPane(m_panelWorkRequest, wxAuiPaneInfo()
								.Name(wxT("wr")).Caption(_("Work requests"))
								.Left()
								.MaximizeButton(true));

	m_panelTask = new PanelTask(this);
	m_aui.AddPane(m_panelTask, wxAuiPaneInfo()
								.Name(wxT("task")).Caption(_("Tasks"))
								.Right()
								.MaximizeButton(true));

	m_panelCost = new PanelCost(this);
	m_aui.AddPane(m_panelCost, wxAuiPaneInfo()
								.Name(wxT("cost")).Caption(_("Costs"))
								.Right()
								.MaximizeButton(true));
								
	m_panelTag = new PanelTag(this);
	m_aui.AddPane(m_panelTag, wxAuiPaneInfo()
								.Name(wxT("tag")).Caption(_("Tags"))
								.Left());
								
	m_panelIndicator = new PanelIndicator(this);
	m_aui.AddPane(m_panelIndicator, wxAuiPaneInfo()
								.Name(wxT("indicator")).Caption(_("Indicators"))
								.Center()
								.CloseButton(false).MinimizeButton(true).MaximizeButton(true));

	Maximize();

	wxString perspective;
	if (wxConfigBase::Get()->Read(KEY_PERSPECTIVE, &perspective)) {
		m_aui.LoadPerspective(perspective, false);
	}

	m_aui.Update();
	
	m_fileHistory.Load(*wxConfigBase::Get());
	m_fileHistory.UseMenu(m_menuRecentFiles);
	m_fileHistory.AddFilesToMenu();

	Connect(wxID_FILE1, wxID_FILE9, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnFileMRU), NULL, this);

	wxTheApp->Connect(pmEVT_PROJECT_LOADED, wxCommandEventHandler(MainFrame::OnProjectLoaded), NULL, this);
}

MainFrame::~MainFrame()
{
	wxConfigBase::Get()->Write(KEY_PERSPECTIVE, m_aui.SavePerspective());
	m_fileHistory.Save(*wxConfigBase::Get());
	m_aui.UnInit();
}

int MainFrame::GetActiveProject() const
{
	return dynamic_cast<IdClientData*>(m_listProject->GetClientObject(m_listProject->GetSelection()))->id();
}

void MainFrame::OpenFile(const wxString& filename)
{
	if (pm::load(filename) == false) {
		wxMessageBox(_("Error while opening file"), _("ProjectManager error"), wxOK|wxICON_ERROR);
		return;
	}
	m_fileHistory.AddFileToHistory(filename);
	
	wxCommandEvent evt(pmEVT_PROJECT_LOADED);
	evt.SetInt(1);
	wxPostEvent(wxTheApp, evt);
}

void MainFrame::OnProjectLoaded(wxCommandEvent& event)
{
	event.Skip();
	wxLogMessage(wxT("MainFrame::OnProjectLoaded(%d)"), event.GetInt());
	
	m_listProject->Clear();
	
	pm::ListProject listProject;
	pm::select_all(listProject);
	BOOST_FOREACH(const pm::Project& project, listProject) {
		m_listProject->Append(project.name(), new IdClientData(project.id()));
	}
	m_listProject->SetSelection(0);
}

void MainFrame::OnCloseFrame(wxCloseEvent& WXUNUSED(event))
{
	Destroy();
}

void MainFrame::OnExitClick(wxCommandEvent& WXUNUSED(event))
{
	Destroy();
}

void MainFrame::OnFileNew( wxCommandEvent& WXUNUSED(event) )
{
	// Disable pm events
	wxCommandEvent cnxEvt(pmEVT_CONNECT_EVENTS);
	cnxEvt.SetInt(0);
	wxPostEvent(wxTheApp, cnxEvt);
	
	// Launch wizard
	WizardNewProject wiz(this);
	if (wiz.RunWizard(wiz.GetFirstPage())) {
		m_fileHistory.AddFileToHistory(wiz.GetFileName());
	}

	// Enable pm events
	cnxEvt.SetInt(1);
	wxPostEvent(wxTheApp, cnxEvt);
}

void MainFrame::OnFileOpen( wxCommandEvent& WXUNUSED(event) )
{
	wxFileDialog dlg(this, _("Select the project file"), wxEmptyString, wxEmptyString, wxT("database file (*.pmdb)|*.pmdb"));
	if (dlg.ShowModal() != wxID_OK) {
		return;
	}
	OpenFile(dlg.GetPath());
}

void MainFrame::OnFileMRU( wxCommandEvent& event )
{
	wxString filename = m_fileHistory.GetHistoryFile(event.GetId() - wxID_FILE1);
	if (!wxFile::Exists(filename)) {
		m_fileHistory.RemoveFileFromHistory(event.GetId() - wxID_FILE1);
		wxLogMessage(wxT("File %s doesn't exists anymore."));
		return;
	}
	
	OpenFile(filename);
}

void MainFrame::OnFileSave( wxCommandEvent& WXUNUSED(event) )
{
	
}

void MainFrame::OnNewCost( wxCommandEvent& WXUNUSED(event) )
{
	DlgNewCost dlg(this);
	dlg.ShowModal();
}

void MainFrame::OnMenuViewSelection( wxCommandEvent& event )
{
	wxString paneName;
	switch (event.GetId())
	{
	case ID_MENU_VIEW_COST        : paneName = wxT("cost");     break;
	case ID_MENU_VIEW_TASK        : paneName = wxT("task");     break;
	case ID_MENU_VIEW_SUMARY      : paneName = wxT("summary");  break;
	case ID_MENU_VIEW_WORKREQUEST : paneName = wxT("wr");       break;
	case ID_MENU_VIEW_LOG         : paneName = wxT("log");      break;
	case ID_MENU_VIEW_TAG         : paneName = wxT("tag");      break;
	default: return;
	}
	m_aui.GetPane(paneName).Show( event.IsChecked() );
	m_aui.Update();
}

void MainFrame::OnMenuViewUpdateUI( wxUpdateUIEvent& event )
{
	wxString paneName;
	switch (event.GetId())
	{
	case ID_MENU_VIEW_COST        : paneName = wxT("cost");     break;
	case ID_MENU_VIEW_TASK        : paneName = wxT("task");     break;
	case ID_MENU_VIEW_SUMARY      : paneName = wxT("summary");  break;
	case ID_MENU_VIEW_WORKREQUEST : paneName = wxT("wr");       break;
	case ID_MENU_VIEW_LOG         : paneName = wxT("log");      break;
	case ID_MENU_VIEW_TAG         : paneName = wxT("tag");      break;
	default: return;
	}
	event.Check( m_aui.GetPane(paneName).IsShown() );
}

void MainFrame::OnAbout( wxCommandEvent& WXUNUSED(event) )
{
	DlgAbout dlg(this);
	dlg.ShowModal();
}
